.POSIX:

### TARGETS:
##   make all (default) - compile and link everything
##   make image - make all, and prepare the disk image (rudely uses sudo!)
##   make qemu  - make image, and run qemu
##   make bochs - make image, and run bochs
##   make clear - delete generated files

CC = gcc

## All C sources that make up the kernel
CFILES = Core/main.c Core/multiboot.c Core/memory.c \
         Core/task.c Drivers/text_video.c Drivers/keyboard.c \
         Core/cpuid.c Core/mp_tables.c Core/smbios.c \
         Core/acpi.c Drivers/pci.c UI/shell.c UI/stdcmds.c

## All NASM sources that make up the kernel
SFILES = Core/loader.asm Core/task_switch.asm

## Compiler settings (also takes settings from the environmenmt)
CFLAGS += -O0 -m32 -DCPU=686 -D__SMP__ -mtune=i686 -IHeaders \
          -ffreestanding -nostdlib -Werror -Wall -Wextra \
          -pedantic -pedantic-errors -Wformat-security -Wformat-nonliteral \
          -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings \
          -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls \
          -Wnested-externs -Winline -Wno-long-long -Wstrict-prototypes \
          -std=c99 -Wno-unused -fpack-struct -fmerge-all-constants
              
## Linker settings (also takes settings from the environment)
LDFLAGS += -nostdlib --fatal-warnings

## All directories that have to be created before Building
DIRS = Build/ $(addprefix Build/,Core/ Drivers/ UI/ )

## The file that indicates the directories have been created
MKDIRS = Build/.mkdirs.done

## Directory to mount disk image to
MOUNTDIR = mnt

##################

DEPFILES = $(addprefix Build/,$(CFILES:.c=.d))

.PHONY: all clean image qemu bochs
all: # default target

## dependency tracking

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPFILES)
endif

$(DEPFILES): Build/%.d: %.c $(MKDIRS)
	./depend.sh Build/$(dir $<) $(CFLAGS) $*.c > $@

all: Build/kernel.elf

$(MKDIRS):
	for i in $(DIRS); do [ -d $$i ] || mkdir -v $$i; done
	touch $@

Build/kernel.elf: $(MKDIRS) link.ld $(addprefix Build/,$(CFILES:.c=.o) $(SFILES:.asm=.o))
	$(LD) $(LDFLAGS) -m elf_i386 -Tlink.ld -o $@ $(addprefix Build/,$(SFILES:.asm=.o) $(CFILES:.c=.o))
	
$(addprefix Build/,$(CFILES:.c=.o)): Build/%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

$(addprefix Build/,$(SFILES:.asm=.o)): Build/%.o: %.asm
	nasm -O0 $< -f elf32 -o $@

clean:
	$(RM) -r Build/
	$(RM) bootable.iso
	$(RM) isofiles/cdrom/boot/kernel.elf

image: Build/kernel.elf
	{ \
	    cp Build/kernel.elf isofiles/cdrom/boot/kernel.elf ;\
		genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o cdrom.iso isofiles/cdrom ;\
		sudo mount -o loop floppy.img mnt/ ;\
		sudo cp Build/kernel.elf mnt/boot/kernel.elf ;\
		sudo umount mnt/ ;\
	}

all: image

floppy: Build/kernel.elf
	{ \
		sudo mount -o loop floppy.img mnt/ ;\
		sudo cp Build/kernel.elf mnt/boot/kernel.elf ;\
		sudo dd if=floppy.img of=/dev/fd0 bs=512 ;\
		sudo umount mnt/ ;\
	}
    
qemu: image
	qemu -m 32 -smp 2 -boot d -cdrom cdrom.iso

bochs: image
	bochs
	
